package cn.sc.summer.redis.util;

import cn.sc.summer.constant.redis.RedisConstant;
import cn.sc.summer.constant.regex.RegexConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 类名：ip限制工具类
 *
 * @author a-xin
 * @date 2024/1/22 13:58
 */
@Slf4j
@Component
public class IpLimitUtil {

    /**
     * 将ip加入访问黑名单
     *
     * @param ipAddress ip地址
     * @param time      锁定时间，-1为永久
     * @param timeUnit  锁定时间单位
     */
    public static void addBlackList(@NonNull String ipAddress, @NonNull Long time, @NonNull TimeUnit timeUnit) {
        if (!ipAddress.matches(RegexConstant.IP_REGEX)) {
            throw new RuntimeException("The IP format is incorrect！");
        }
        RedisHelper.set(RedisConstant.IP_BLACK_LIST + ipAddress, System.currentTimeMillis(), time, timeUnit);
    }

    /**
     * 将ip和限制路径加入访问黑名单
     *
     * @param ipAddress ip地址
     * @param time      锁定时间，-1为永久
     * @param timeUnit  锁定时间单位
     * @param path      限制路径
     */
    public static void addBlackList(@NonNull String ipAddress, @NonNull Long time, @NonNull TimeUnit timeUnit, @NonNull String path) {
        if (!ipAddress.matches(RegexConstant.IP_REGEX)) {
            throw new RuntimeException("The IP format is incorrect！");
        }
        RedisHelper.set(RedisConstant.IP_BLACK_LIST + ipAddress + path, path, time, timeUnit);
    }

    /**
     * 移除ip地址所有的黑名单权限
     *
     * @param ipAddress ip地址
     */
    public static void removeBlackList(@NonNull String ipAddress) {
        if (!ipAddress.matches(RegexConstant.IP_REGEX)) {
            throw new RuntimeException("The IP format is incorrect！");
        }
        RedisHelper.delKeysByPrefix(RedisConstant.IP_BLACK_LIST + ipAddress);
    }

    /**
     * 移除ip和指定路径的黑名单权限
     *
     * @param ipAddress ip地址
     * @param path      限制路径
     */
    public static void removeBlackList(@NonNull String ipAddress, @NonNull String path) {
        if (!ipAddress.matches(RegexConstant.IP_REGEX)) {
            throw new RuntimeException("The IP format is incorrect！");
        }
        RedisHelper.del(RedisConstant.IP_BLACK_LIST + ipAddress + path);
    }

    /**
     * 查询该ip地址是否加入黑名单
     *
     * @param ipAddress ip地址
     * @return ture：可以访问，false：限制访问
     */
    public static Boolean checkBlackList(@NonNull String ipAddress) {
        if (!ipAddress.matches(RegexConstant.IP_REGEX)) {
            throw new RuntimeException("The IP format is incorrect！");
        }
        return !RedisHelper.hasKey(RedisConstant.IP_BLACK_LIST + ipAddress);
    }

    /**
     * 查询该ip地址和访问路径是否加入黑名单
     *
     * @param ipAddress ip地址
     * @param path      访问路径
     * @return ture：可以访问，false：限制访问
     */
    public static Boolean checkBlackList(@NonNull String ipAddress, @NonNull String path) {
        if (!ipAddress.matches(RegexConstant.IP_REGEX)) {
            throw new RuntimeException("The IP format is incorrect！");
        }
        return !RedisHelper.hasKey(RedisConstant.IP_BLACK_LIST + ipAddress + path);
    }

}
